package com.yuanxin.track;


import android.database.Cursor;
import android.util.Log;

import com.facebook.react.modules.network.OkHttpClientProvider;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.yuanxin.track.dbTables.DaoSession;
import com.yuanxin.track.dbTables.UserActiveLogModel;
import com.yuanxin.track.dbTables.UserActiveLogModelDao;
import com.yuanxin.track.dbTables.UserLoginLogModel;
import com.yuanxin.track.dbTables.UserLoginLogModelDao;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * 数据上传工具类
 */
public class DataUploadManager {

    private static final String TAG = TrackModule.class.getSimpleName();

    private static DataUploadManager dataUploadManager;
    private DaoSession daoSession;

    private boolean isLoginUpload = false;


    private int loginUploadErrCount = 1;


    private DataUploadManager(DaoSession daoSession) {
        this.daoSession = daoSession;
    }

    static void init(DaoSession daoSession) {
        if (dataUploadManager == null) {//如果对象为空，new 一个新对象，并且开始上传
            dataUploadManager = new DataUploadManager(daoSession);
        }
    }


    static void start() {
        Log.d(TAG, "uploadLogin check :" + (!dataUploadManager.isLoginUpload));
        if (!dataUploadManager.isLoginUpload) {
            dataUploadManager.isLoginUpload = true;
            dataUploadManager.loginUploadErrCount = 1;
            dataUploadManager.uploadLogin();
        }

    }


    private synchronized void uploadLogin() {
        List<UserLoginLogModel> userLoginLogModelList = daoSession.getUserLoginLogModelDao().loadAll();
        if (userLoginLogModelList == null || userLoginLogModelList.size() == 0) {
            isLoginUpload = false;
            return;
        }
        Log.d(TAG, "userLoginLogModelList  : " + userLoginLogModelList.size());

        for (UserLoginLogModel userLoginLogModel : userLoginLogModelList) {
            uploadLog(userLoginLogModel);
        }
    }


    /**
     * 上传登录日志
     */
    public synchronized void uploadLog(UserLoginLogModel userLoginLogModel) {
        Log.d(TAG, "开始上传用户日志uploadLoginLog : " + loginUploadErrCount);


        Log.d(TAG, "用户->登录日志  : " + userLoginLogModel.toString());

        final List<UserActiveLogModel> userActiveLogModelList = daoSession.getUserActiveLogModelDao().
                queryBuilder().where(UserActiveLogModelDao.Properties.LoginId.eq(userLoginLogModel.getId())).list();
        final UploadBean uploadBean = new UploadBean();
        uploadBean.userLoginLog = userLoginLogModel;
        String uploadJson = new Gson().toJson(uploadBean);
        JsonObject jsonObject = new JsonParser().parse(uploadJson).getAsJsonObject();
        // 后台接口改动：如果登录日志没有上传成功，先单独上传一次登录日志，跟随行为日志一起上传的登录日志后台现在不做重复上传，以免记录重复的登录日志
        boolean hasActiveLog = (userActiveLogModelList != null && userActiveLogModelList.size() > 0);
        final boolean needUploadLoginFirst = (userLoginLogModel.getIsUploadSuccess()!=1 && hasActiveLog);
        if (hasActiveLog) {
            uploadBean.userActiveLogs = userActiveLogModelList.subList(0, userActiveLogModelList.size() > 50 ? 50 : userActiveLogModelList.size());
            uploadJson = new Gson().toJson(uploadBean);
            jsonObject = new JsonParser().parse(uploadJson).getAsJsonObject();
            for (int i = 0; jsonObject.getAsJsonArray("userActiveLogs") != null && i < jsonObject.getAsJsonArray("userActiveLogs").size(); i++) {
                JsonElement eventDataJsonElement = jsonObject.getAsJsonArray("userActiveLogs").get(i).getAsJsonObject().get("eventData");
                if (eventDataJsonElement != null) {
                    String eventData = eventDataJsonElement.getAsString();
                    JsonObject jsonObject1 = new JsonParser().parse(eventData).getAsJsonObject();
                    jsonObject.getAsJsonArray("userActiveLogs").get(i).getAsJsonObject().remove("eventData");
                    jsonObject.getAsJsonArray("userActiveLogs").get(i).getAsJsonObject().add("eventData", jsonObject1);
                }
            }
        }

        Log.d(TAG, "uploadJson : " + jsonObject.toString());
        Log.d(TAG, "URL : " + Constants.URL_CollectUserLogs);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString());
        final Request request = new Request.Builder()
                .url(Constants.URL_CollectUserLogs)
                .post(requestBody)
                .build();
        Call call = OkHttpClientProvider.getOkHttpClient().newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "用户日志 onError ：" + e.getMessage());
                if (loginUploadErrCount < 3) {
                    loginUploadErrCount++;
                    uploadLogin();
                } else {
                    isLoginUpload = false;
                    Log.d(TAG, "用户日志失败三次");
                }
            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) {
                if (response != null && response.code() == 200) {
                    try {
                        UploadRequestResult requestResult = new Gson().fromJson(response.body().string(), UploadRequestResult.class);
                        Log.d(TAG, "用户日志 onResponse ：" + requestResult.toString());
                        if (requestResult.isSuccess()) {
                            uploadBean.userLoginLog.setIsUploadSuccess(1);
                            daoSession.getUserLoginLogModelDao().insertOrReplace(uploadBean.userLoginLog);
                            //这里不清理登录日志，只清理行为日志
                            daoSession.getUserActiveLogModelDao().deleteInTx(userActiveLogModelList);
                            cleanData();
                            // 需要先上传登录日志后上传行为日志的，需要再走一遍。。临时尽量少的改动适配，后续需优化
                            if (needUploadLoginFirst) {
                                uploadLogin();
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    isLoginUpload = false;
                } else {
                    if (loginUploadErrCount < 3) {
                        loginUploadErrCount++;
                        uploadLogin();
                    } else {
                        isLoginUpload = false;
                        Log.d(TAG, "用户日志失败三次");
                    }
                }
            }
        });
    }



    public void cleanData() {
        daoSession.getUserActiveLogModelDao().queryBuilder().where(UserActiveLogModelDao.Properties.LoginId.eq("null"))
                .buildDelete().executeDeleteWithoutDetachingEntities();
        Cursor cursor = daoSession.getDatabase().rawQuery("select * from " + UserLoginLogModelDao.TABLENAME + " where "
                + UserLoginLogModelDao.Properties.LoginTime.columnName + " <> (select max(" + UserLoginLogModelDao.Properties.LoginTime.columnName
                + ") from " + UserLoginLogModelDao.TABLENAME + ") and "+UserLoginLogModelDao.Properties.Id.columnName
                +" not in (select "+UserActiveLogModelDao.Properties.LoginId.columnName+" from "+UserActiveLogModelDao.TABLENAME
                +") and "+UserLoginLogModelDao.Properties.IsUploadSuccess.columnName+" = 1", null);
        List<String> list = new ArrayList<>();
        if (cursor.moveToFirst()) {
            do {
                list.add(cursor.getString(cursor.getColumnIndexOrThrow("ID")));
            } while (cursor.moveToNext());
        }
        cursor.close();
        daoSession.getUserLoginLogModelDao().deleteByKeyInTx(list);
    }
}
